package com.mathlearning.auth.service;

import com.mathlearning.auth.common.BusinessException;
import com.mathlearning.auth.dto.learning.admin.*;
import com.mathlearning.auth.entity.*;
import com.mathlearning.auth.repository.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.util.Arrays;
import java.util.List;

@Service
@Slf4j
public class LearningAdminService {
    
    @Autowired
    private LearningCategoryRepository categoryRepository;
    
    @Autowired
    private LearningCourseRepository courseRepository;
    
    @Autowired
    private LearningChapterRepository chapterRepository;
    
    @Autowired
    private LearningVideoRepository videoRepository;
    
    @Autowired
    private OSSService ossService;
    
    private static final List<String> ALLOWED_VIDEO_TYPES = Arrays.asList(
        "video/mp4", "video/avi", "video/mov", "video/flv"
    );
    
    private static final List<String> ALLOWED_IMAGE_TYPES = Arrays.asList(
        "image/jpeg", "image/jpg", "image/png", "image/webp"
    );
    
    private static final long MAX_VIDEO_SIZE = 500 * 1024 * 1024; // 500MB
    private static final long MAX_IMAGE_SIZE = 5 * 1024 * 1024; // 5MB
    
    // ==================== 分类管理 ====================
    
    /**
     * 创建课程分类
     */
    @Transactional
    public CategoryResponse createCategory(CreateCategoryRequest request) {
        LearningCategory category = LearningCategory.builder()
            .name(request.getName())
            .icon(request.getIcon())
            .sortOrder(request.getSortOrder() != null ? request.getSortOrder() : 0)
            .build();
        
        category = categoryRepository.save(category);
        
        return CategoryResponse.builder()
            .id(category.getId())
            .name(category.getName())
            .icon(category.getIcon())
            .sortOrder(category.getSortOrder())
            .build();
    }
    
    // ==================== 课程管理 ====================
    
    /**
     * 创建课程
     */
    @Transactional
    public CourseResponse createCourse(CreateCourseRequest request, Long currentUserId) {
        // 验证分类是否存在
        categoryRepository.findById(request.getCategoryId())
            .orElseThrow(() -> new BusinessException("课程分类不存在"));
        
        // 如果前端没有传讲师ID，使用当前登录用户
        Long instructorId = request.getInstructorId();
        if (instructorId == null) {
            instructorId = currentUserId;
        }
        
        LearningCourse course = LearningCourse.builder()
            .categoryId(request.getCategoryId())
            .title(request.getTitle())
            .description(request.getDescription())
            .cover(request.getCover())
            .difficulty(request.getDifficulty() != null ? request.getDifficulty() : "beginner")
            .instructorId(instructorId)
            .status(request.getStatus() != null ? request.getStatus() : "draft")
            .videoCount(0)
            .studentCount(0)
            .sortOrder(0)
            .build();
        
        course = courseRepository.save(course);
        
        return CourseResponse.builder()
            .id(course.getId())
            .title(course.getTitle())
            .cover(course.getCover())
            .description(course.getDescription())
            .difficulty(course.getDifficulty())
            .status(course.getStatus())
            .createdAt(course.getCreatedAt())
            .build();
    }
    
    /**
     * 更新课程
     */
    @Transactional
    public CourseResponse updateCourse(Long courseId, UpdateCourseRequest request) {
        LearningCourse course = courseRepository.findById(courseId)
            .orElseThrow(() -> new BusinessException("课程不存在"));
        
        // 更新字段（只更新非null的字段）
        if (request.getCategoryId() != null) {
            categoryRepository.findById(request.getCategoryId())
                .orElseThrow(() -> new BusinessException("课程分类不存在"));
            course.setCategoryId(request.getCategoryId());
        }
        
        if (request.getTitle() != null) {
            course.setTitle(request.getTitle());
        }
        
        if (request.getDescription() != null) {
            course.setDescription(request.getDescription());
        }
        
        if (request.getCover() != null) {
            course.setCover(request.getCover());
        }
        
        if (request.getDifficulty() != null) {
            course.setDifficulty(request.getDifficulty());
        }
        
        if (request.getInstructorId() != null) {
            course.setInstructorId(request.getInstructorId());
        }
        
        if (request.getStatus() != null) {
            course.setStatus(request.getStatus());
        }
        
        course = courseRepository.save(course);
        
        return CourseResponse.builder()
            .id(course.getId())
            .title(course.getTitle())
            .cover(course.getCover())
            .description(course.getDescription())
            .difficulty(course.getDifficulty())
            .status(course.getStatus())
            .createdAt(course.getCreatedAt())
            .build();
    }
    
    /**
     * 删除课程
     */
    @Transactional
    public void deleteCourse(Long courseId) {
        LearningCourse course = courseRepository.findById(courseId)
            .orElseThrow(() -> new BusinessException("课程不存在"));
        
        // 删除课程会级联删除所有章节、视频和学习进度记录（通过数据库外键）
        courseRepository.delete(course);
        
        log.info("删除课程: courseId={}, title={}", courseId, course.getTitle());
    }
    
    // ==================== 章节管理 ====================
    
    /**
     * 创建章节
     */
    @Transactional
    public ChapterResponse createChapter(Long courseId, CreateChapterRequest request) {
        // 验证课程是否存在
        courseRepository.findById(courseId)
            .orElseThrow(() -> new BusinessException("课程不存在"));
        
        LearningChapter chapter = LearningChapter.builder()
            .courseId(courseId)
            .title(request.getTitle())
            .description(request.getDescription())
            .sortOrder(request.getSortOrder() != null ? request.getSortOrder() : 0)
            .build();
        
        chapter = chapterRepository.save(chapter);
        
        return ChapterResponse.builder()
            .id(chapter.getId())
            .courseId(chapter.getCourseId())
            .title(chapter.getTitle())
            .sortOrder(chapter.getSortOrder())
            .build();
    }
    
    // ==================== 视频管理 ====================
    
    /**
     * 创建视频
     */
    @Transactional
    public VideoResponse createVideo(Long chapterId, CreateVideoRequest request) {
        // 验证章节是否存在
        LearningChapter chapter = chapterRepository.findById(chapterId)
            .orElseThrow(() -> new BusinessException("章节不存在"));
        
        LearningVideo video = LearningVideo.builder()
            .chapterId(chapterId)
            .courseId(chapter.getCourseId())
            .title(request.getTitle())
            .description(request.getDescription())
            .videoUrl(request.getVideoUrl())
            .duration(request.getDuration() != null ? request.getDuration() : 0)
            .thumbnail(request.getThumbnail())
            .sortOrder(request.getSortOrder() != null ? request.getSortOrder() : 0)
            .viewCount(0)
            .accessType(request.getAccessType() != null ? request.getAccessType() : "free")
            .previewDuration(request.getPreviewDuration() != null ? request.getPreviewDuration() : 0)
            .build();
        
        video = videoRepository.save(video);
        
        // 更新课程的视频数量
        updateCourseVideoCount(chapter.getCourseId());
        
        return VideoResponse.builder()
            .id(video.getId())
            .chapterId(video.getChapterId())
            .title(video.getTitle())
            .sortOrder(video.getSortOrder())
            .build();
    }
    
    /**
     * 上传视频文件
     */
    public VideoUploadResponse uploadVideo(MultipartFile file) {
        // 验证文件类型
        String contentType = file.getContentType();
        if (contentType == null || !ALLOWED_VIDEO_TYPES.contains(contentType)) {
            throw new BusinessException("不支持的视频格式，仅支持: mp4, avi, mov, flv");
        }
        
        // 验证文件大小（最大500MB）
        if (file.getSize() > MAX_VIDEO_SIZE) {
            throw new BusinessException("视频文件过大，最大支持500MB");
        }
        
        try {
            // 上传到OSS
            String videoUrl = ossService.uploadFile(file, "videos");
            
            // 注意：这里无法获取视频时长，需要前端使用视频播放器获取时长后传递
            // 或者在服务器端使用FFmpeg等工具解析视频时长
            
            return VideoUploadResponse.builder()
                .videoUrl(videoUrl)
                .duration(0)  // 前端需要在创建视频时提供
                .size(file.getSize())
                .build();
        } catch (Exception e) {
            log.error("视频上传失败", e);
            throw new BusinessException("视频上传失败: " + e.getMessage());
        }
    }
    
    /**
     * 上传课程封面
     */
    public CoverUploadResponse uploadCover(MultipartFile file) {
        // 验证文件类型
        String contentType = file.getContentType();
        if (contentType == null || !ALLOWED_IMAGE_TYPES.contains(contentType)) {
            throw new BusinessException("不支持的图片格式，仅支持: jpg, jpeg, png, webp");
        }
        
        // 验证文件大小（最大5MB）
        if (file.getSize() > MAX_IMAGE_SIZE) {
            throw new BusinessException("图片文件过大，最大支持5MB");
        }
        
        try {
            // 上传到OSS
            String coverUrl = ossService.uploadFile(file, "covers");
            
            return CoverUploadResponse.builder()
                .coverUrl(coverUrl)
                .build();
        } catch (Exception e) {
            log.error("封面上传失败", e);
            throw new BusinessException("封面上传失败: " + e.getMessage());
        }
    }
    
    // ==================== 私有辅助方法 ====================
    
    /**
     * 更新课程的视频数量
     */
    private void updateCourseVideoCount(Long courseId) {
        Long videoCount = videoRepository.countByCourseId(courseId);
        courseRepository.updateVideoCount(courseId, videoCount.intValue());
    }
}



